package com.yuwen.yuwenRPC.server;

import com.yuwen.RpcApplication;
import com.yuwen.yuwenRPC.model.RpcRequest;
import com.yuwen.yuwenRPC.model.RpcResponse;
import com.yuwen.yuwenRPC.registry.LocalRegistry;
import com.yuwen.yuwenRPC.serializer.Serializer;
import com.yuwen.yuwenRPC.serializer.SerializerFactory;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;

import java.io.IOException;
import java.lang.reflect.Method;

/**
 * @ClassNameHttpServerHandler
 * @Description TODO
 * @Author钰玟
 * @Date2025/3/29 下午9:19
 * @Version 1.0
 **/

/**
 * Http请求处理
 */
public class HttpServerHandler implements Handler<HttpServerRequest> {
    @Override
    public void handle(HttpServerRequest httpServerRequest) {
        //序列化器
        final Serializer serializer = SerializerFactory.getSerializer(RpcApplication.getRpcConfig().getSerializer());


        //记录日志
        System.out.println("Received Method " +httpServerRequest.method() +" "+ httpServerRequest.uri());

        //异步处理 http请求
        httpServerRequest.bodyHandler(body->{
           //获取请求 字节流
            byte[] bytes = body.getBytes();
            RpcRequest rpcRequest = null;
            // 反序列化为 rpcRequest 对象
            try {
                rpcRequest = serializer.deserialize(bytes, RpcRequest.class);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //构造 响应 RpcResponse
            RpcResponse rpcResponse = new RpcResponse();
            if(rpcRequest == null) {
                rpcResponse.setMessage("rpcRequest == null");
                doResponse(httpServerRequest,rpcResponse,serializer);
                return;
            }
            //rpcRequest 不是 null
            try {
                // 通过 rpcRequest得到相关信息
                //1. 从注册服务中心获取serviceName
                Class<?> implClass = LocalRegistry.get(rpcRequest.getServiceName());
                // 2. 由serviceName通过反射得到 方法
                Method method = implClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
                // 3. 反射 执行方法
                Object result = method.invoke(implClass.newInstance(), rpcRequest.getParameters());
                // 4. 封装数据
                rpcResponse.setData(result);
                rpcResponse.setReturnType(method.getReturnType());
                rpcResponse.setMessage("ok");

            } catch (Exception e) {
                //异常
                e.printStackTrace();
                rpcResponse.setException(e);
                rpcResponse.setMessage(e.getMessage());
            }
            //5. 响应
            doResponse(httpServerRequest,rpcResponse,serializer);

        });

    }

    /**
     * 响应
     * @param httpServerRequest 请求
     * @param rpcResponse 响应model
     * @param serializer 序列化器
     */
    void doResponse (HttpServerRequest httpServerRequest, RpcResponse rpcResponse, Serializer serializer) {
        HttpServerResponse httpServerResponse = httpServerRequest.response()
                .putHeader("Content-Type","application/json");
        try {
            byte[] serialized = serializer.serialize(rpcResponse);
            //返回序列化后的数据
            httpServerResponse.end(Buffer.buffer(serialized));
        } catch (IOException e) {
            e.printStackTrace();
            //异常 返回 空
            httpServerResponse.end(Buffer.buffer());
        }
    }
}
